package top.goldenyear.porpoise.system.permission.service;

import com.easy.query.api.proxy.client.EasyEntityQuery;
import java.util.ArrayList;
import java.util.List;

import com.easy.query.solon.annotation.Db;
import lombok.extern.slf4j.Slf4j;
import cn.hutool.v7.core.collection.CollUtil;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;
import top.goldenyear.porpoise.common.core.exception.ErrorCode;
import top.goldenyear.porpoise.common.core.exception.ServiceException;
import top.goldenyear.porpoise.framework.web.core.model.PageResult;
import top.goldenyear.porpoise.framework.web.core.model.query.QPage;
import top.goldenyear.porpoise.framework.web.core.service.BaseService;
import top.goldenyear.porpoise.system.account.model.Account;
import top.goldenyear.porpoise.system.account.service.AccountService;
import top.goldenyear.porpoise.system.permission.dto.RoleAccountReq;
import top.goldenyear.porpoise.system.permission.dto.RoleAccountsReq;
import top.goldenyear.porpoise.system.permission.model.AccountRole;
import top.goldenyear.porpoise.system.permission.model.Role;
import top.goldenyear.porpoise.system.permission.model.base.BaseAccountRole;
import top.goldenyear.porpoise.system.permission.model.proxy.AccountRoleProxy;

/**
 * 账户角色表 Service 服务层
 *
 * @author airhead
 * @since 2024-10-12
 */
@Component
@Slf4j
public class AccountRoleService extends BaseService<AccountRole, AccountRoleProxy> {
  @Db
  private EasyEntityQuery easyEntityQuery;
  @Inject private RoleService roleService;
  @Inject private AccountService accountService;

  public AccountRoleService() {
    super(AccountRole.class, AccountRoleProxy.class);
  }

  public Boolean addRoleAccount(RoleAccountReq roleAccountReq) {
    if (roleAccountReq == null
        || roleAccountReq.getAccountId() == null
        || roleAccountReq.getRoleId() == null) {
      throw new ServiceException(ErrorCode.builder().msg("参数不能为空").build());
    }

    AccountRole dbAccountRole =
        get(
            accountRoleProxy -> {
              accountRoleProxy.roleId().eq(roleAccountReq.getRoleId());
              accountRoleProxy.accountId().eq(roleAccountReq.getAccountId());
            });
    // 已经存在无需添加
    if (dbAccountRole != null) {
      return true;
    }

    AccountRole newAccountRole = new AccountRole();
    newAccountRole.setRoleId(roleAccountReq.getRoleId());
    newAccountRole.setAccountId(roleAccountReq.getAccountId());

    return save(newAccountRole);
  }

  public Boolean updateAccountRole(Integer accountId, List<String> roleCodes) {
    delete(accountRoleProxy -> accountRoleProxy.accountId().eq(accountId));

    if (CollUtil.isEmpty(roleCodes)) {
      return true;
    }

    List<Role> roleList = roleService.listRole(roleCodes, 1);
    List<AccountRole> list = new ArrayList<>();
    for (Role role : roleList) {
      AccountRole accountRole = new AccountRole();
      accountRole.setAccountId(accountId);
      accountRole.setRoleId(role.getId());
      list.add(accountRole);
    }

    return batchSave(list);
  }

  public Boolean updateRoleAccount(RoleAccountsReq roleAccountsReq) {
    Integer roleId = roleAccountsReq.getRoleId();
    if (roleId == null) {
      throw new ServiceException(ErrorCode.builder().msg("角色 id 不能为空").build());
    }

    delete(accountRoleProxy -> accountRoleProxy.roleId().eq(roleId));
    if (CollUtil.isEmpty(roleAccountsReq.getAccountIdList())) {
      return true;
    }

    List<AccountRole> list = new ArrayList<>();
    for (Integer accountId : roleAccountsReq.getAccountIdList()) {
      AccountRole accountRole = new AccountRole();
      accountRole.setRoleId(roleId);
      accountRole.setAccountId(accountId);
      list.add(accountRole);
    }

    return batchSave(list);
  }

  public Boolean deleteByUser(Integer userId) {
    if (userId == null) {
      return false;
    }

    return delete(
            accountRoleProxy -> {
              accountRoleProxy.accountId().eq(userId);
            })
        > 0;
  }

  public Boolean deleteByUsers(List<Integer> userIds) {
    if (CollUtil.isEmpty(userIds)) {
      return false;
    }

    return delete(
            accountRoleProxy -> {
              accountRoleProxy.accountId().in(userIds);
            })
        > 0;
  }

  public Boolean deleteByRole(Integer roleId) {
    if (roleId == null) {
      return false;
    }

    return delete(
            accountRoleProxy -> {
              accountRoleProxy.roleId().eq(roleId);
            })
        > 0;
  }

  public List<AccountRole> listRoleAccount(Integer roleId) {
    return list(rolePermissionProxy -> rolePermissionProxy.roleId().eq(roleId));
  }

  public PageResult<Account> paginateRoleAccount(Integer roleId, QPage qPage) {
    List<AccountRole> roleAccountList = listRoleAccount(roleId);
    if (CollUtil.isEmpty(roleAccountList)) {
      return PageResult.empty();
    }

    List<Integer> accountIdList =
        roleAccountList.stream().map(BaseAccountRole::getAccountId).toList();
    PageResult<Account> pageResult =
        accountService.paginate(
            qPage, rolePermissionProxy -> rolePermissionProxy.id().in(accountIdList));
    for (Account record : pageResult.getRecords()) {
      record.removeSensitiveInfo();
    }

    return pageResult;
  }

  public List<AccountRole> listAccountRoleByAccountId(Integer accountId) {
    return easyEntityQuery
        .queryable(AccountRole.class)
        .where(accountRoleProxy -> accountRoleProxy.accountId().eq(accountId))
        .include(AccountRoleProxy::role)
        .toList();
  }

  public PageResult<AccountRole> paginateAccountRole(QPage qPage, AccountRole accountRole) {
    return paginate(qPage.getPageNumber(), qPage.getPageSize(), accountRole);
  }

  @Override
  protected EasyEntityQuery easyEntityQuery() {
    return easyEntityQuery;
  }
}
